﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Management;
using System.Text;
using System.Windows.Forms;

namespace Cataloger
{
    /// <summary>
    /// Statyczna klasa będąca zbiorem metod statycznych
    /// dotyczących napędów komputera
    /// </summary>
    public static class Drive
    {
		#region Methods (16) 

		// Public Methods (15) 

        /// <summary>
        /// Metoda zwraca tablicę obiektów klasy DriveInfo,
        /// które reprezentują dyskietkę 3,5
        /// </summary>
        /// <returns></returns>
        public static DriveInfo[] Dyskietki()
        {
            List<DriveInfo> dyski = new List<DriveInfo>();
            
            foreach (DriveInfo disc in DriveInfo.GetDrives())
            {
          
                if (disc.IsReady && disc.DriveType == DriveType.Removable && (disc.Name.StartsWith("A") || disc.Name.StartsWith("B")))
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        /// <summary>
        /// Metoda zbierająca informacje o wszytskich dyskach fizycznych w komputerze.
        /// Zbiera informacje o Nazwie dysku logicznego oraz nazwie dysku fizycznego
        /// na którym się znajduje.
        /// </summary>
        /// <param name="partdysk">SortedList w której przechowywana będzie informacja nazwie dysku logicznego(klucz)
        /// oraz o nazwie dysku fizycznego na którym się znajduje (wartość)</param>
        public static void DyskiFizyczne(SortedList<string,string>partdysk)
        {
            List<string>dyski=new List<string>();
            ManagementClass devs = new ManagementClass("Win32_Diskdrive");
            {
                ManagementObjectCollection moc = devs.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    try
                    {
                        dyski.Add(mo["Name"].ToString()
                        +" "+mo["Model"].ToString()
                        + " \tPartycje: " + mo["Partitions"].ToString()
                        +"\n"
                       );
                    }
                    catch { }                   
                    foreach (ManagementObject b in mo.GetRelated("Win32_DiskPartition"))
                    {
                        foreach (ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk"))
                        {
                            try
                            {
                                partdysk[c["Name"].ToString()] = dyski[dyski.Count - 1];
                            }
                            catch { }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Wykrywa wszytskie gotowe dyski (IsReady=true).
        /// Oznacza to, że w napędzie jest nośnik.
        /// </summary>
        /// <returns>Zwraca tablicę obiektów DriveInfo bedących gotowymi dyskami</returns>
        public static DriveInfo[] DyskiGotowe()
        {
            List<DriveInfo> dyski = new List<DriveInfo>();
            foreach (DriveInfo disc in DriveInfo.GetDrives() )
            {
                if (disc.IsReady)
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        public static DriveInfo[] DyskiOptyczne()
        {
            List<DriveInfo> dyski = new List<DriveInfo>();
            foreach (DriveInfo disc in DriveInfo.GetDrives())
            {            
                if (disc.IsReady && disc.DriveType == DriveType.CDRom)
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        public static DriveInfo[] DyskiSieciowe()
        {
            List<DriveInfo> dyski = new List<DriveInfo>();
            foreach (DriveInfo disc in DriveInfo.GetDrives() )
            {
       
                if (disc.IsReady && disc.DriveType == DriveType.Network)
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        public static DriveInfo[] DyskiTwarde()
        {

            List<DriveInfo> dyski = new List<DriveInfo>();
            foreach (DriveInfo disc in DriveInfo.GetDrives() )
            {
                if (disc.IsReady && disc.DriveType == DriveType.Fixed)
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        public static DriveInfo[] DyskiWymienne()
        {
            List<DriveInfo> dyski = new List<DriveInfo>();
            foreach (DriveInfo disc in DriveInfo.GetDrives() )
            {
              
                if (disc.IsReady && disc.DriveType == DriveType.Removable)
                {
                    dyski.Add(disc);
                }
            }
            return dyski.ToArray();
        }

        public static string InformacjeORozmiarze()
        {
            StringBuilder opis = new StringBuilder();

            opis.AppendLine("Całkowity rozmiar: \t" + Drive.RozmiarCalkowity().ToProperUnit());
            opis.AppendLine("=========================");
            opis.AppendLine("Miejsca wolnego: \t" + Drive.WolneCalkowite().ToProperUnit());
            opis.AppendLine("Miejsca zajętego: \t" + Drive.ZajeteCalkowite().ToProperUnit());
            return opis.ToString();

        }

        public static string OpisIleNosnikow()
        {
            StringBuilder opis = new StringBuilder();

            opis.AppendLine("Dostępne nośniki: \t"+Drive.DyskiGotowe().Length.ToString());
            opis.AppendLine("=================");
            opis.AppendLine("Dyski twarde: \t"+Drive.DyskiTwarde().Length.ToString());
            opis.AppendLine("Dyski optyczne: \t"+Drive.DyskiOptyczne().Length.ToString());
            opis.AppendLine("Dyski przenośne: \t"+Drive.DyskiWymienne().Length.ToString());
            opis.AppendLine("Dyski sieciowe: \t"+Drive.DyskiSieciowe().Length.ToString());
            return opis.ToString();
        }

        /// <summary>
        /// Fukncja do obliczania stosunku miejsca zajetego do całkowitego wyrażonego w procentach będących liczbami całkiwtymi
        /// Napisana na potrzeby rysowania odpowiedniego wykresu
        /// </summary>
        /// <returns>Zwraca procentową zajętość w liczbach całkowitych np. 11, 25 etc.</returns>
        public static int ProcentowoZajetosc()
        {
            //Drive.ZajeteCalkowite();
            decimal procent = ((decimal)Drive.ZajeteCalkowite()/(decimal)Drive.RozmiarCalkowity() ) * 100;

            return decimal.ToInt32(procent);
        }

        /// <summary>
        /// Metoda oblicza całkowity rozmiar gotowych dysków
        /// </summary>
        /// <returns>Rozmiar wszytskich gotowych dysków w bajtach</returns>
        public static long RozmiarCalkowity()
        {
            long ile = 0;
            foreach (DriveInfo di in DriveInfo.GetDrives() )
            {
                if(di.IsReady)
                ile += di.TotalSize;
            }
            return ile;
        }

        /// <summary>
        /// Metoda oblicza ilość wolnego miejsca na wszytskich gotowych dyskach
        /// </summary>
        /// <returns>Rozmiar wolnej przestrzeni gotowych dysków w bajtach</returns>
        public static long WolneCalkowite()
        {
            long ile = 0;
            foreach (DriveInfo di in DriveInfo.GetDrives())
            {
                if(di.IsReady)
                ile += di.AvailableFreeSpace;
            }
            return ile;
        }

        /// <summary>
        /// Metoda rysuje wykres "PieChart" stosunku miejsca wolnego do zajętego w wybranym
        /// PictureBoxie
        /// </summary>
        /// <param name="picture">Miejsce docelowe rysowanego wykresu</param>
        public static void WykresZajetoscCalkowita(PictureBox picture)
        {
            long calosc = Drive.RozmiarCalkowity();
            long wolne = Drive.WolneCalkowite();
            float angle = 360 * ((float)wolne / (float)calosc);///kat jaki ma zakreślić od 0 do angle zajęte miejsce

            Graphics.FromHwnd(picture.Handle).FillPie(new SolidBrush(Color.Red), 0, 0, picture.Width, picture.Height, 0, 360);
            Graphics.FromHwnd(picture.Handle).FillPie(new SolidBrush(Color.Blue), 0, 0, picture.Width, picture.Height, 0, angle);
            picture.Paint += new PaintEventHandler(picture_Paint);
        }

        /// <summary>
        /// Metoda rysuje wykres na pasku postępu ProgressBar stosunku miejsca wolnego do zajętego w wybranym ProgressBarze
        /// </summary>
        /// <param name="progress">ProgressBar na którym ma się narysować zależność</param>
        public static void WykresZajetoscCalkowita(ProgressBar progress)
        {
            int k = 10000;
            progress.Maximum = (Int32)(Drive.RozmiarCalkowity() / k);
            progress.Value = (Int32)(Drive.ZajeteCalkowite() / k);
           
        }

        public static long ZajeteCalkowite()
        {
            return RozmiarCalkowity() - WolneCalkowite();
        }
		// Private Methods (1) 

        static void picture_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillPie(new SolidBrush(Color.Red), 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height, 0, 360);
            e.Graphics.FillPie(new SolidBrush(Color.Blue), 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height, 0, 360 * ((float)Drive.WolneCalkowite() / (float)Drive.RozmiarCalkowity()));
        }

		#endregion Methods 
    }
}
